using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;

namespace SpoonCore
{
	public class ClientInfo : IComparable<ClientInfo>
	{
		private SpoonIdentifier _id;
		private readonly List<IPEndPoint> _endpointList = new List<IPEndPoint>();
		private readonly SpoonClient _client;

		public ClientInfo(SpoonClient client, SpoonIdentifier id)
		{
			_client = client;
			_id = id;
		}

		public ClientInfo(SpoonClient client, BinaryReader br)
		{
			_client = client;
			_id = new SpoonIdentifier(br);
			int count = br.ReadInt32();
			while (count > 0)
			{
				_endpointList.Add(new IPEndPoint(new IPAddress(br.ReadBytes(4)), br.ReadInt32()));
				count--;
			}
		}

		public byte[] GetBytes()
		{
			MemoryStream stream = new MemoryStream();
			BinaryWriter bw = new BinaryWriter(stream);

			bw.Write(_id.GetBytes());
			bw.Write(_endpointList.Count);
			foreach (IPEndPoint point in _endpointList)
			{
				bw.Write(point.Address.GetAddressBytes());
				bw.Write(point.Port);
			}

			return stream.ToArray();
		}

		public SpoonIdentifier Id
		{
			get { return _id; }
			set { _id = value; }
		}

		public IPEndPoint[] Endpoints
		{
			get { return _endpointList.ToArray(); }
		}

		public void AddEndpoint(IPEndPoint endpoint)
		{
			if (!_endpointList.Contains(endpoint)) _endpointList.Add(endpoint);
		}

		public void AddEndpoint(IEnumerable<IPEndPoint> endpoints)
		{
			foreach (IPEndPoint point in endpoints)
			{
				AddEndpoint(point);
			}
		}

		public void Send(IMessage msg)
		{
			_client.Send(this, msg);
		}

		public override string ToString()
		{
			string res = _id + " (";
			for (int x = 0; x < _endpointList.Count; x++)
			{
				res += _endpointList[x];
				if (x < _endpointList.Count - 1) res += ", ";
			}
			res += ")";
			return res;
		}

		public int CompareTo(ClientInfo other)
		{
			if (other == null) return -1;
			return _id.CompareTo(other._id);
		}

		public override bool Equals(object obj)
		{
			if (obj is ClientInfo) return _id.Equals(((ClientInfo)obj).Id);
			else return base.Equals(obj);
		}

		public override int GetHashCode()
		{
			return _id.GetHashCode();
		}
	}
}
